﻿using System.Linq;
using System.Web;
using Microsoft.AspNetCore.Http;
using Senparc.CO2NET;
using Senparc.CO2NET.Trace;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.MvcExtension;

namespace Web.Controllers.Filter
{
    /// <summary>
    /// 微信OAuth授权验证，可以加在Action或整个Controller上,默认为snsapi_base方式授权
    /// OAuthScope.snsapi_base方式授权"/oauth2/BaseCallback"
    /// OAuthScope.snsapi_userinfo方式授权"/oauth2/UserInfoCallback"
    /// 调用方式，在控制器或Action上添加：
    /// [CustomOAuth(null)]或者[CustomOAuth(null,"/oauth2/BaseCallback",OAuthScope.snsapi_base)]//OAuthScope.snsapi_base方式授权
    /// [CustomOAuth(null,"/oauth2/UserInfoCallback",OAuthScope.snsapi_userinfo)]//OAuthScope.snsapi_base方式授权
    /// </summary>
    public class CustomOAuthAttribute : SenparcOAuthAttribute
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="oauthCallbackUrl"></param>
        /// <param name="oauthScope"></param>
        public CustomOAuthAttribute(string appId, string oauthCallbackUrl = "/oauth2/BaseCallback", OAuthScope oauthScope = OAuthScope.snsapi_base)
            : base(appId, oauthCallbackUrl,oauthScope)
        {
            base._appId = base._appId ?? Senparc.Weixin.Config.SenparcWeixinSetting.WeixinAppId;
        }

        /// <summary>
        /// 重复判断是否登录的方法
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public override bool IsLogined(HttpContext httpContext)
        {
            //BLL.NLogHelper.Debug(string.Format("授权验证IsAuthenticated:{0},openid:{1}", httpContext.User.Identity.IsAuthenticated, httpContext.User.Identity.Name));

            //如果是多租户，也可以这样写，通过 URL 参数来区分：
            //base._appId = httpContext.Request.Query["appId"].FirstOrDefault();//appId也可以是数据库存储的Id，避免暴露真实的AppId

            //.NET Core 3.0 中，Attribute 似乎会在系统初始化的时候进行第一次初始化（执行构造函数），而不是在第一次需要被访问到的时候。
            //因此，构造函数中的 appId 等默认值未必可以有赋值（当时 其他对象都还没有值），这里为了确保 appId 有值，再次进行判断。
            base._appId = base._appId ?? Senparc.Weixin.Config.SenparcWeixinSetting.WeixinAppId;
            return httpContext != null && httpContext.User.Identity.IsAuthenticated;
        }        
    }
}
